static void
symmetry_test (ICC *state);
-char *
-babl_space_to_icc (const Babl *babl,
- const char *description,
- const char *copyright,
- BablICCFlags flags,
- int *ret_length)
+
+static char *
+babl_space_to_icc_rgb (const Babl *babl,
+ const char *description,
+ const char *copyright,
+ BablICCFlags flags,
+ int *ret_length)
{
const BablSpace *space = &babl->space;
char icc[65536];
}
}
+
+static char *
+babl_space_to_icc_gray (const Babl *babl,
+ const char *description,
+ const char *copyright,
+ BablICCFlags flags,
+ int *ret_length)
+{
+ const BablSpace *space = &babl->space;
+ char icc[65536];
+ int length=65535;
+ ICC *state = icc_state_new (icc, length, 10);
+
+ icc[length]=0;
+
+ symmetry_test (state);
+
+ icc_write (sign, 4, "babl"); // ICC verison
+ icc_write (u8, 8, 2); // ICC verison
+ icc_write (u8, 9, 0x20); // 2.2 for now..
+ icc_write (u32,64, 0); // rendering intent
+
+ icc_write (s15f16,68, 0.96421); // Illuminant
+ icc_write (s15f16,72, 1.0);
+ icc_write (s15f16,76, 0.82491);
+
+ icc_write (sign, 80, "babl"); // creator
+
+ icc_write (sign, 12, "mntr");
+ icc_write (sign, 16, "GRAY");
+ icc_write (sign, 20, "XYZ ");
+
+ icc_write (u16, 24, 2222); // babl profiles
+ icc_write (u16, 26, 11); // should
+ icc_write (u16, 28, 11); // use a fixed
+ icc_write (u16, 30, 3); // date
+ icc_write (u16, 32, 44); // that gets updated
+ icc_write (u16, 34, 55); // when the generator changes
+
+ icc_write (sign, 36, "acsp"); // changes
+
+ {
+ state->tags = 6; /* note: we could reserve a couple of spots and
+ still use a very simple allocator and
+ still be valid - albeit with tiny waste of
+ space.
+ */
+ state->no = state->o = 128 + 4 + 12 * state->tags;
+
+ icc_write (u32, 128, state->tags);
+
+ icc_allocate_tag (state, "wtpt", 20);
+ icc_write (sign, state->o, "XYZ ");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (s15f16, state->o + 8, space->whitepoint[0]);
+ icc_write (s15f16, state->o + 12, space->whitepoint[1]);
+ icc_write (s15f16, state->o + 16, space->whitepoint[2]);
+
+ write_trc (state, "kTRC", &space->trc[0]->trc, flags);
+
+ {
+ char str[128]="CC0/public domain";
+ int i;
+ if (!copyright) copyright = str;
+ icc_allocate_tag(state, "cprt", 8 + strlen (copyright) + 1);
+ icc_write (sign, state->o, "text");
+ icc_write (u32, state->o + 4, 0);
+ for (i = 0; copyright[i]; i++)
+ icc_write (u8, state->o + 8 + i, copyright[i]);
+ }
+ {
+ char str[128]="babl";
+ int i;
+ if (!description) description = str;
+ icc_allocate_tag(state, "desc", 90 + strlen (description) + 0);
+ icc_write (sign, state->o,"desc");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (u32, state->o + 8, strlen(description) + 1);
+ for (i = 0; description[i]; i++)
+ icc_write (u8, state->o + 12 + i, description[i]);
+ }
+ icc_write (u32, 0, state->no + 0);
+ length = state->no + 0;
+ }
+
+ if (ret_length)
+ *ret_length = length;
+
+ babl_free (state);
+ {
+ char *ret = malloc (length);
+ memcpy (ret, icc, length);
+ return ret;
+ }
+}
+
+char *
+babl_space_to_icc (const Babl *babl,
+ const char *description,
+ const char *copyright,
+ BablICCFlags flags,
+ int *ret_length)
+{
+ if (babl->space.icc_type == BablICCTypeRGB)
+ return babl_space_to_icc_rgb (babl, description, copyright, flags,
+ ret_length);
+ else if (babl->space.icc_type == BablICCTypeGray)
+ return babl_space_to_icc_gray (babl, description, copyright, flags,
+ ret_length);
+ fprintf (stderr, "unexpected icc type in %s\n", __FUNCTION__);
+ return NULL;
+}
+
const char *
babl_space_get_icc (const Babl *babl,
int *length)
const Babl *trc_red = NULL;
const Babl *trc_green = NULL;
const Babl *trc_blue = NULL;
+ const Babl *trc_gray = NULL;
const char *int_err;
Babl *ret = NULL;
int speed_over_accuracy = intent & BABL_ICC_INTENT_PERFORMANCE;
+ int is_gray = 0;
sign_t profile_class, color_space, pcs;
ret = _babl_space_for_lcms (icc_data, icc_length);
if (ret->space.icc_type == BablICCTypeCMYK)
return ret;
- ret->space.icc_type = BablICCTypeCMYK;
ret->space.icc_length = icc_length;
ret->space.icc_profile = malloc (icc_length);
memcpy (ret->space.icc_profile, icc_data, icc_length);
return ret;
}
- if (strcmp (color_space.str, "RGB "))
- *error = "not defining an RGB space";
+
+
+
+ if (strcmp (color_space.str, "RGB ")
+#if 0 /* XXX: commented out, as gimp-2.99 doesn't like loading grayscale jpegs with grayscale icc profiles when it is enabled */
+ && strcmp (color_space.str, "GRAY")
+#endif
+ )
+ {
+ *error = "not defining RGB, CMYK or GRAY space..";
+ }
else
{
if (strcmp (profile_class.str, "mntr"))
*error = "not a monitor-class profile";
+ if (!strcmp (color_space.str, "GRAY"))
+ is_gray = 1;
}
}
{
trc_blue = babl_trc_from_icc (state, offset, error);
}
+ if (!*error && icc_tag (state, "kTRC", &offset, &element_size))
+ {
+ trc_gray = babl_trc_from_icc (state, offset, error);
+ }
}
- if (!*error && (!trc_red || !trc_green || !trc_blue))
+ if (is_gray)
{
- *error = "missing TRCs";
+ if (!*error && (!trc_gray))
+ {
+ *error = "missing TRC";
+ }
+ }
+ else
+ {
+ if (!*error && (!trc_red || !trc_green || !trc_blue))
+ {
+ *error = "missing TRCs";
+ }
}
if (*error)
return NULL;
}
+ if (is_gray)
+ {
+ int offset, element_size;
+ if (icc_tag (state, "wtpt", &offset, &element_size))
+ {
+ // wX = icc_read (s15f16, offset + 8);
+ // wY = icc_read (s15f16, offset + 8 + 4);
+ // wZ = icc_read (s15f16, offset + 8 + 4 * 2);
+ }
+ ret = (void*)babl_space_from_gray_trc (NULL, trc_gray, 1);
+ ret->space.icc_length = icc_length;
+ ret->space.icc_profile = malloc (icc_length);
+ memcpy (ret->space.icc_profile, icc_data, icc_length);
+ babl_free (state);
+ return ret;
+
+
+ *error = "gray parsing NYI";
+ }
+ else
+ {
if (icc_tag (state, "rXYZ", NULL, NULL) &&
icc_tag (state, "gXYZ", NULL, NULL) &&
icc_tag (state, "bXYZ", NULL, NULL) &&
return ret;
}
}
-
*error = "didnt find RGB primaries";
+ }
+
babl_free (state);
return NULL;
}
memset (&space, 0, sizeof(space));
space.instance.class_type = BABL_SPACE;
space.instance.id = 0;
+ space.icc_type = BablICCTypeCMYK;
if (i >= MAX_SPACES-1)
{
space.RGBtoXYZ[6] = rz;
space.RGBtoXYZ[7] = gz;
space.RGBtoXYZ[8] = bz;
+ space.icc_type = BablICCTypeRGB;
babl_matrix_invert (space.RGBtoXYZ, space.XYZtoRGB);
babl_matrix_to_float (space.RGBtoXYZ, space.RGBtoXYZf);
babl_matrix_to_float (space.XYZtoRGB, space.XYZtoRGBf);
+ /* recover chromaticities from matrix */
{
double red[3]={1.,.0,.0};
double xyz[3]={1.,.0,.0};
space.whitepoint[0] = wx / wy;
space.whitepoint[1] = 1.0;
space.whitepoint[2] = (1.0 - wx - wy) / wy;
+ space.icc_type = BablICCTypeRGB;
for (i = 0; space_db[i].instance.class_type; i++)
{
return (Babl*)&space_db[i];
}
+const Babl *
+babl_space_from_gray_trc (const char *name,
+ const Babl *trc_gray,
+ BablSpaceFlags flags)
+{
+ int i=0;
+ BablSpace space = {0,};
+ space.instance.class_type = BABL_SPACE;
+ space.instance.id = 0;
+
+ space.xw = 0.3127;
+ space.yw = 0.3290;
+
+ space.xr = 0.639998686;
+ space.yr = 0.330010138;
+ space.xg = 0.300003784;
+ space.yg = 0.600003357;
+ space.xb = 0.150002046;
+ space.yb = 0.059997204;
+ space.trc[0] = trc_gray;
+ space.trc[1] = trc_gray;
+ space.trc[2] = trc_gray;
+
+ space.whitepoint[0] = space.xw / space.yw;
+ space.whitepoint[1] = 1.0;
+ space.whitepoint[2] = (1.0 - space.xw - space.yw) / space.yw;
+ space.icc_type = BablICCTypeGray;
+
+ for (i = 0; space_db[i].instance.class_type; i++)
+ {
+ int offset = ((char*)&space_db[i].xr) - (char*)(&space_db[i]);
+ int size = ((char*)&space_db[i].trc) + sizeof(space_db[i].trc) - ((char*)&space_db[i].xr);
+
+ if (memcmp ((char*)(&space_db[i]) + offset, ((char*)&space) + offset, size)==0)
+ {
+ return (void*)&space_db[i];
+ }
+ }
+ if (i >= MAX_SPACES-1)
+ {
+ babl_log ("too many BablSpaces");
+ return NULL;
+ }
+ space_db[i]=space;
+ space_db[i].instance.name = space_db[i].name;
+ if (name)
+ snprintf (space_db[i].name, sizeof (space_db[i].name), "%s", name);
+ else
+ /* XXX: this can get longer than 256bytes ! */
+ snprintf (space_db[i].name, sizeof (space_db[i].name),
+ "space-gray-%s", babl_get_name(space.trc[0]));
+
+ /* compute matrixes */
+ babl_space_compute_matrices (&space_db[i], 1);
+
+ //babl_space_get_icc ((Babl*)&space_db[i], NULL);
+ return (Babl*)&space_db[i];
+
+}
+
+
void
babl_space_class_for_each (BablEachFunction each_fun,
void *user_data)
return space?space->space.icc_type == BablICCTypeCMYK:0;
}
+int
+babl_space_is_gray (const Babl *space)
+{
+ return space?space->space.icc_type == BablICCTypeGray:0;
+}
+
+
/* Trademarks:
*
* International Color Consortium is a registered trademarks of the.